package org.celery.client.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.celery.client.service.ClientOrderService;
import org.celery.common.utils.IPUtil;
import org.celery.modules.goods.entity.GoodsStyle;
import org.celery.modules.goods.service.IGoodsService;
import org.celery.modules.order.entity.Order;
import org.celery.modules.order.enums.*;
import org.celery.modules.order.service.IOrderService;
import org.celery.modules.order.vo.OrderVO;
import org.celery.modules.order.wrapper.OrderWrapper;
import org.celery.modules.user.service.IUserDomainService;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.jackson.JsonUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.User;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("order")
@Api(value = "订单")
public class ClientOrderController {

    private final ClientOrderService clientOrderService;
    private final IOrderService orderService;
    private final IUserDomainService userDomainService;
    private final IGoodsService goodsService;

    /**
     * 订单提交
     */
    @PostMapping("/submit")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "订单提交")
    public R<Order> submit(@RequestBody Order order, HttpServletRequest request) {
        synchronized (this) {
            BigDecimal goodsAmount = clientOrderService.computeTotalAmount(order.getAssociatedGoods());
            BigDecimal logisticsFee = clientOrderService.computeLogisticsFee(order.getShippingAddress(), request.getServerName());
            order.setGoodsAmountTotal(goodsAmount);
            order.setLogisticsFee(logisticsFee);
            order.setTotalAmount(goodsAmount.add(logisticsFee));
            order.setGoodsCount(JsonUtil.parseArray(order.getAssociatedGoods(), GoodsStyle.class).size());
            order.setPayChannel(PayChannelEnum.CASH_ON_DELIVERY.getStatus());
            order.setPayStatus(OrderStatusPayEnum.PENDING.getStatus());
            order.setStatus(OrderStatusEnum.NORMAL.getStatus());
            order.setShipStatus(OrderStatusShipEnum.TO_BE_CONFIRM.getStatus());

            String ip = IPUtil.getIpAddr(request);
            String ipAndArea = IPUtil.getCityInfo(ip);

            order.setFromDomain(request.getServerName());
            if (Func.isEmpty(ipAndArea)) {
                order.setFromIp(ip);
            } else {
                order.setFromIp(ipAndArea + "-" + ip);
            }
            // 默认为1 => 台湾 TODO - 后续需要做多地区
            order.setArea(1);

            // 获取域名关联的用户, 并设置订单出单人、租户
            User fromUser = userDomainService.selectUserByDomain(request.getServerName());
            if (Func.isNotEmpty(fromUser)) {
                order.setFromUser(fromUser.getId());
                order.setTenantId(fromUser.getTenantId());
            }
            order.setCode(orderService.getOrderCode(Func.isEmpty(fromUser) ? "" : fromUser.getTenantId()));

            // 获取历史订单量
            QueryWrapper<Order> historyCountQueryWrapper = new QueryWrapper<>();
            historyCountQueryWrapper.lambda().eq(Order::getFromDomain, request.getServerName())
                    .eq(Order::getReceiverPhone, order.getReceiverPhone())
                    .or().eq(Order::getFromIp, ip);
            if (Func.isNotEmpty(order.getReceiverEmail())) {
                historyCountQueryWrapper.lambda().or().eq(Order::getReceiverEmail, order.getReceiverEmail());
            }
            int historyCount = orderService.count(historyCountQueryWrapper);

            order.setIsNew(historyCount == 0 ? OrderIsNewEnum.NEW.getType() : OrderIsNewEnum.OLD.getType());

            if (!orderService.save(order)) {
                throw new ServiceException("訂單創建失敗!");
            }

            // 修改商品销量
            goodsService.addSell(order);
        }

        return R.data(order);
    }

    /**
     * 订单详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "订单详情")
    public R<OrderVO> detail(String orderId) {
        Order order = orderService.getById(orderId);
        return R.data(Func.isEmpty(order) ? null : OrderWrapper.build().entityVO(order));
    }

    /**
     * 运费计算
     */
    @PostMapping("/compute-logistics-fee")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "运费计算")
    public R<BigDecimal> computeLogisticsFee(@RequestParam("address") String address, HttpServletRequest request) {
        return R.data(clientOrderService.computeLogisticsFee(address, request.getServerName()));
    }

}
